package cn.hzc.fortess.core.shiro.service.impl;


import cn.hzc.fortess.system.common.EnableStatus;
import cn.hzc.fortess.core.common.SpringContextHolder;
import cn.hzc.fortess.core.shiro.ShiroKit;
import cn.hzc.fortess.core.shiro.ShiroUser;
import cn.hzc.fortess.core.shiro.service.UserAuthService;
import cn.hzc.fortess.system.dao.LesseeDao;
import cn.hzc.fortess.system.dao.MenuDao;
import cn.hzc.fortess.system.dao.UserDao;
import cn.hzc.fortess.system.entity.Lessee;
import cn.hzc.fortess.system.entity.Role;
import cn.hzc.fortess.system.entity.User;

import cn.hzc.fortess.system.service.RoleService;
import com.google.common.collect.Lists;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@DependsOn("springContextHolder")
@Transactional(readOnly = true)
public class UserAuthServiceServiceImpl implements UserAuthService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private LesseeDao lesseeDao;

    @Autowired
    private RoleService roleService;

    public static UserAuthService me() {
        return SpringContextHolder.getBean(UserAuthService.class);
    }

    @Override
    public User getUserByLoginName(String account) {

        User user = userDao.getUserByAccount(account);

        // 账号不存在
        if (null == user) {
            throw new CredentialsException();
        }
        // 账号被冻结
        if (Objects.equals(user.getStatus(), EnableStatus.DISABLE.getStatus())) {
            throw new DisabledAccountException();
        }

        Lessee lessee = lesseeDao.findById(user.getLesseeId());

        if (lessee == null || Objects.equals(lessee.getStatus(), EnableStatus.DISABLE.getStatus())) {
            throw new AuthenticationException("无效的登录!");
        }

        return user;
    }

    @Override
    public ShiroUser createShiroUser(User user) {
        final ShiroUser shiroUser = ShiroKit.createShiroUser(user);
        final List<Role> userRoles = roleService.getByUser(user.getUserId());
        shiroUser.setRoleList(userRoles);
        return shiroUser;
    }

    /**
     * 根据角色获取该角色所有授权标识
     */
    @Override
    public List<String> findPermissionsByRoleId(Integer roleId) {
        List<Integer> roles = Lists.newArrayList();
        roles.add(roleId);
        final List<String> permissions = roleService.findMenuPermissionListByRoleIds(roles);
        return permissions.parallelStream().filter(url -> StringUtils.isNotBlank(url)).collect(Collectors.toList());
    }


    @Override
    public SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName) {
        String credentials = user.getPassword();
        // 密码加盐处理
        String source = user.getSalt();
        ByteSource credentialsSalt = new Md5Hash(source);
        return new SimpleAuthenticationInfo(shiroUser, credentials, credentialsSalt, realmName);
    }

}
